#ifndef _SOURCE_SCAN_HPP_
#define _SOURCE_SCAN_HPP_

#include <cstdio>
#include <stdint.h>
#include <vector>



template <typename DataProcessor>
class SourceScan
{
    DataProcessor &_processor;


public:
    SourceScan(DataProcessor &processor)
        : _processor(processor)
    {
    }


    int ReadFile(const char *filename)
    {
        char buf[4096];
        std::vector<uint32_t> book_ids;
        int count = 0;

        FILE *f = fopen(filename, "rt");
        if (f == NULL)
            return -1;
       
        while(fgets(buf, 4096, f) != NULL) {
            uint32_t id = 0;
            char *cur = buf, *cur_end = cur + 4096;

            /* get uid */
            for(; *cur != ':' && cur < cur_end; cur++) {
                id = id * 10 + *cur - '0';
            }

            /* get bookid */
            id = 0;
            for(cur++; *cur != '\n' && *cur != '\0' && cur < cur_end; cur++) {
                if (*cur == ',') {
                    book_ids.push_back(id);
                    id = 0;
                    continue;
                }

                id = id * 10 + *cur - '0';
            }

            if (id > 0)
                book_ids.push_back(id);

            uint32_t weight = 1;
            if (book_ids.size() <= 4)
                weight = 2; //strong relaion if one user collects few items

            for(size_t i = 0; i < book_ids.size(); i++)  {
                _processor.AddFreq(book_ids[i]);
                for(size_t j = i + 1; j < book_ids.size(); j++) 
                    _processor.Process(book_ids[i], book_ids[j], weight);
            }

            if (++count % 10000 == 0) {
                printf("progress: %d\n", count);
            }

            book_ids.clear();
        }

        fclose(f);
        return 0;
    }

};

#endif

